home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / file-tra / fsp-2.7 / fsp-2 / fsp / server / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-21  |  17.8 KB  |  598 lines

  1.     /*********************************************************************\
  2.     *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  3.     *                                                                     *
  4.     *  You may copy or modify this file in any manner you wish, provided  *
  5.     *  that this notice is always included, and that you hold the author  *
  6.     *  harmless for any loss or damage resulting from the installation or *
  7.     *  use of this software.                                              *
  8.     \*********************************************************************/
  9.  
  10. #include "tweak.h"
  11. #include "server_def.h"
  12. #include "s_extern.h"
  13. #include "version.h"
  14.  
  15. #ifdef __STDC__
  16. #include <stdarg.h>
  17. #else
  18. #include <varargs.h>
  19. #endif
  20.  
  21. #ifdef VMS
  22. #define FSP_STAT vms_stat
  23. #else
  24. #define FSP_STAT stat
  25. #endif
  26.  
  27. #define ACTIONLOG0(X) \
  28. do{ if(!old) { \
  29.   fsplogs(); \
  30.   fsploga("%s %s", inetstr, (X)); \
  31. } } while (0)
  32.  
  33. #define ACTIONLOG1(X) \
  34. do { if(!old) { \
  35.   fsplogs(); \
  36.   fsploga("%s %-8s /%.*s", inetstr, (X), l1, s1); \
  37. } } while (0)
  38.  
  39. #define ACTIONINFO(F) \
  40. do { if(!old) { \
  41.   fsploga F; \
  42. } } while (0)
  43.  
  44. #define ACTIONFAILED(M) \
  45. do { if(!old) { \
  46.   fsploga(": ERROR %s\n", (M)); \
  47.   fsplogf(); \
  48. } } while (0)
  49.  
  50. #define ACTIONOK() \
  51. do { if(!old) { \
  52.   fsploga("\n"); \
  53.   fsplogf(); \
  54. } } while (0)
  55.  
  56. #ifdef VMS  /* for the freopen() function */
  57. # define NULL_DEV "nl:"
  58. #else
  59. # define NULL_DEV "/dev/null"
  60. #endif
  61.  
  62. int max_nlen = FILE_NAME_LIMIT;
  63. int inetd_mode = 0;
  64. int dir_cache_limit = MAX_DIR_CACHE_COUNT;
  65. int logfd = -1;  /* logfile file descriptor */
  66.  
  67. extern int daemonize;
  68. extern int dbug;
  69. extern int logging;
  70. extern int priv_mode;
  71. extern int read_only;
  72. extern int no_unnamed;
  73. extern int udp_port;
  74. extern int run_uid;
  75. extern char *logname;
  76. extern unsigned int maxthcallowed;
  77.  
  78. char *config_file = 0 ;
  79.  
  80. /****************************************************************************
  81.  * A slightly better logging function.. It now takes a format string and    *
  82.  * any number of args.                                                      *
  83.  * The file is opened and closed so that I can run a cron job to summarize  *
  84.  * the file, then remove the already summarized portion automatically       *
  85.  * without worrying about the file descriptors pointing to a file that no   *
  86.  * longer really exists.                                                    *
  87.  ****************************************************************************/
  88. #define LOGBUFFER 1024
  89. static char logbuf[LOGBUFFER];    /* buffer for log message */
  90. static int logpos = 0;        /* current log message length */
  91.  
  92. /* append some text to the log message */
  93. #ifdef __STDC__
  94. static void fsploga(const char *fmt, ...)
  95. #else
  96. static void fsploga(va_alist)
  97.   va_dcl
  98. #endif
  99. {
  100. #ifdef __STDC__
  101.   va_list args;
  102. #else
  103.   char *fmt;
  104.   va_list args;
  105. #endif
  106.  
  107.   if(logging && logfd >= 0) { /* don't log if we don't have a logfile */
  108. #ifdef __STDC__
  109.     va_start(args, fmt);
  110. #else
  111.     va_start(args);
  112.     fmt = va_arg(args, char *);
  113. #endif
  114.     vsprintf(logbuf + logpos, fmt, args);
  115.     logpos += strlen(logbuf + logpos);
  116.     va_end(args);
  117.   }
  118. }
  119.  
  120. /* add a datestamp to the log message */
  121. static void fsplogs PROTO0((void))
  122. {
  123.   struct stat sb;
  124.  
  125.   if(logging && logfd >= 0 && FSP_STAT(logname, &sb) == -1) {
  126.     close(logfd);
  127. #ifdef VMS
  128.     if((logfd = vms_open(logname, "w")) < 0)
  129. #else
  130.     if((logfd = open(logname, O_WRONLY | O_APPEND | O_CREAT, 0644)) < 0)
  131. #endif
  132. {
  133. perror(logname) ;
  134.       logging = 0;
  135. }
  136.   }
  137.   if(logging && logfd >= 0) {  /* don't log if we don't have a logfile */
  138.     time_t sectime; /* current time in seconds */
  139.     int timelen;
  140.     char *timestr;
  141.  
  142.     sectime = time((time_t *)0);
  143.     timestr = (char *)ctime(§ime);
  144.     timelen = strlen(timestr) - 1; /* strip the CR */
  145.     timestr[timelen] = '\0';
  146.     strcpy(logbuf + logpos, timestr);
  147.     logbuf[timelen] = ' ';
  148.     logpos += timelen + 1;
  149.   }
  150. }
  151.  
  152. /* flush the log message to file */
  153. static void fsplogf PROTO0((void))
  154. {
  155.   if(logging && logfd >= 0) { /* don't log if we don't have a logfile */
  156.     write(logfd, logbuf, logpos);
  157.     logpos = 0;
  158.   }
  159. }
  160.  
  161. /****************************************************************************
  162. * Send version information.
  163. * Note: no bounds checking is currently performed.  As version information
  164. *       grows, this will become required.
  165. ****************************************************************************/
  166. static void server_show_version PROTO2(struct sockaddr_in *, from, UBUF *, ub)
  167. {
  168.   char buf[UBUF_SPACE], verflags = 0;
  169.  
  170.   strcpy(buf, VERSION_STR);
  171.   strcat(buf, "\n");
  172.  
  173.   if(logging) verflags |= VER_LOG;
  174.   if (read_only) verflags |= VER_READONLY;
  175.   if (no_unnamed) verflags |= VER_REVNAME;
  176.   if (priv_mode) verflags |= VER_PRIVMODE;
  177.   if (maxthcallowed) verflags |= VER_THRUPUT;
  178.  
  179.   strcpy(ub->buf, buf);
  180.   BB_WRITE4(ub->bb_pos,VER_BYTES);
  181.   ub->buf[strlen(ub->buf)] = '\0';
  182.   ub->buf[strlen(ub->buf)+1] = verflags;
  183.   if(maxthcallowed) {
  184.     BB_WRITE4(ub->bb_pos,VER_BYTES+4);
  185.     ub->buf[strlen(ub->buf)+2] = (char)((maxthcallowed & 0xff000000)>>24);
  186.     ub->buf[strlen(ub->buf)+3] = (char)((maxthcallowed & 0x00ff0000)>>16);
  187.     ub->buf[strlen(ub->buf)+4] = (char)((maxthcallowed & 0x0000ff00)>>8);
  188.     ub->buf[strlen(ub->buf)+5] = (char)(maxthcallowed & 0x000000ff);
  189.     
  190.     server_reply(from, ub, strlen(ub->buf)+1, VER_BYTES+4);
  191.   } else {
  192.     server_reply(from, ub, strlen(ub->buf)+1, VER_BYTES);
  193.   }
  194. }
  195.  
  196. /****************************************************************************
  197. *  This is the dispatch loop for message that has been accepted.
  198. *    bytes: size of the message received.
  199. *       ub: pointer to the message buffer.
  200. *      old: true if this message contains old sequence number (retransmit).
  201. *       hp: pointer to the entry for the client host who sent this message.
  202. *     from: pointer to the socket address structure of the client host.
  203. ****************************************************************************/
  204.  
  205. void server_get_packet PROTO5(int, bytes, UBUF *, ub, int, old,
  206.                   HTAB *, hp, struct sockaddr_in *, from)
  207. {
  208.   unsigned long  inet_num, pos;
  209.   unsigned short port_num;
  210.   unsigned l1, l2;
  211.   char *s1, *s2, *pe, inetstr_buf[128], *inetstr;
  212.   FILE *fp;
  213.   PPATH pp;
  214.   struct stat sd; /* for logging of filesize */
  215.  
  216.   pos = BB_READ4(ub->bb_pos);
  217.   l1  = BB_READ2(ub->bb_len);
  218.   l2 = bytes - l1 - UBUF_HSIZE;
  219.   s1 = ub->buf;
  220.   s2 = ub->buf + l1;
  221.  
  222.   /* put remote inet_number in a var, for logging purposes */
  223.   if (dbug || logging) {
  224.     if (hp->hostname)
  225.       inetstr = hp->hostname;
  226.     else {
  227.       sprintf(inetstr_buf,"%d.%d.%d.%d",
  228.           ((unsigned char *)(&hp->inet_num))[0],
  229.           ((unsigned char *)(&hp->inet_num))[1],
  230.           ((unsigned char *)(&hp->inet_num))[2],
  231.           ((unsigned char *)(&hp->inet_num))[3]);
  232.       inetstr = inetstr_buf;
  233.     }
  234.   }
  235.  
  236.   if(dbug) fprintf(stderr,"rcv (%c,%d,%d,%lu) <--- %s\n", ub->cmd, l1, l2,
  237.            pos, inetstr);
  238.  
  239.   if(!old) {
  240.     hp->last_key = hp->next_key;
  241.     hp->next_key = get_next_key() + ((hp->last_key+1) & 0x00ff);
  242.   }
  243.  
  244.   BB_WRITE2(ub->bb_key,hp->next_key);
  245.   inet_num = hp->inet_num;
  246.   port_num = from->sin_port;
  247.  
  248.   switch(ub->cmd) {
  249.     case CC_VERSION:
  250.       if(logging & L_VER) ACTIONLOG0("VERSION");
  251.       server_show_version(from, ub);
  252.       if(logging & L_VER) ACTIONOK();
  253.       return;
  254.     case CC_BYE:
  255.       if(!old) hp->active = 0;
  256.       server_reply(from,ub,0,0);
  257.       return;
  258.     case CC_GET_DIR :
  259.       if (!pos && (logging & L_GETDIR)) ACTIONLOG1("GETDIR");
  260.       if((pe = check_path(s1,l1,&pp)) ||
  261.          (pe = server_get_dir(&pp, inet_num, &fp))) {
  262.     if (pos && (logging & L_ERR) && (logging & L_GETDIR))
  263.       ACTIONLOG1("GETDIR");
  264.     if ((logging & L_ERR) && (logging & L_GETDIR)) ACTIONFAILED(pe);
  265.         else if (!pos && (logging & L_GETDIR)) ACTIONOK() ;
  266.         send_error(from, ub, pe);
  267.     return;
  268.       }
  269.       send_file(from,ub,fp,l2,s2);
  270.       fclose(fp);
  271.       if (!pos && (logging & L_GETDIR)) ACTIONOK();
  272.       return;
  273.     case CC_GET_FILE:
  274.       if (!pos && (logging & L_GETFILE)) ACTIONLOG1("GETFILE");
  275.       if((pe = check_path(s1,l1,&pp)) ||
  276.      (pe = server_get_file(&pp, &fp, inet_num, port_num))) {
  277.     if (pos && (logging & L_ERR) && (logging & L_GETFILE))
  278.       ACTIONLOG1("GETFILE");
  279.     if ((logging & L_ERR) && (logging & L_GETFILE)) ACTIONFAILED(pe);
  280.         else if (!pos && (logging & L_GETFILE)) ACTIONOK() ;
  281.         send_error(from, ub, pe);
  282.     return;
  283.       }
  284.       if (!pos) {
  285.     FSP_STAT(pp.fullp,&sd); /* log filesizes */
  286.         if (logging & L_GETFILE) ACTIONINFO((" (%d)",sd.st_size));
  287.       }
  288.       send_file(from,ub,fp,l2,s2);
  289.       if (!pos && (logging & L_GETFILE)) ACTIONOK();
  290.       return;
  291.     case CC_DEL_FILE:
  292.       if(logging & L_DELFILE) ACTIONLOG1("DELFILE");
  293.       if (read_only) {
  294.     if((logging & L_ERR) && (logging & L_DELFILE))
  295.        ACTIONFAILED("Permission denied");
  296.         else if (logging & L_DELFILE) ACTIONOK() ;
  297.         send_error(from, ub, "Permission denied");
  298.         return;
  299.       }
  300.       if(!old)
  301.     if((pe = check_path(s1,l1,&pp)) ||
  302.        (pe = server_del_file(&pp,inet_num))) {
  303.       if((logging & L_ERR) && (logging & L_DELFILE)) ACTIONFAILED(pe);
  304.           else if (logging & L_DELFILE) ACTIONOK() ;
  305.           send_error(from, ub, pe) ;
  306.       return;
  307.     }
  308.       server_reply(from,ub,0,0);
  309.       if(logging & L_DELFILE) ACTIONOK();
  310.       return;
  311.     case CC_DEL_DIR :
  312.       if(logging & L_DELDIR) ACTIONLOG1("DELDIR");
  313.       if (read_only) {
  314.     if((logging & L_ERR) && (logging & L_DELDIR))
  315.       ACTIONFAILED("Permission denied");
  316.         else if (logging & L_DELDIR) ACTIONOK() ;
  317.         send_error(from, ub, "Permission denied") ;
  318.     return;
  319.       }
  320.       if(!old)
  321.     if((pe = check_path(s1,l1,&pp)) ||
  322.        (pe = server_del_dir(&pp,inet_num))) {
  323.       if((logging & L_ERR) && (logging & L_DELDIR)) ACTIONFAILED(pe);
  324.           else if (logging & L_DELDIR) ACTIONOK() ;
  325.           send_error(from, ub, pe) ;
  326.       return;
  327.     }
  328.       server_reply(from,ub,0,0);
  329.       if(logging & L_DELDIR) ACTIONOK();
  330.       return;
  331.     case CC_UP_LOAD :
  332.       if (!pos || read_only) {
  333.     if(logging & L_UPLOAD) ACTIONLOG0("UPLOAD");
  334.     if(read_only) {
  335.       if((logging & L_ERR) && (logging & L_UPLOAD))
  336.         ACTIONFAILED("Permission denied");
  337.           else if (logging & L_UPLOAD) ACTIONOK() ;
  338.           send_error(from, ub, "Permission denied") ;
  339.       return;
  340.     }
  341.       }
  342.       if(!old)
  343.     if(pe = server_up_load(s1,l1,pos, inet_num,port_num)) {
  344.       if (pos && (logging & L_ERR) && (logging & L_UPLOAD))
  345.         ACTIONLOG0("UPLOAD");
  346.       if ((logging & L_ERR) && (logging & L_UPLOAD)) ACTIONFAILED(pe);
  347.           else if (!pos && (logging & L_UPLOAD)) ACTIONOK() ;
  348.           send_error(from, ub, pe) ;
  349.       return;
  350.     }
  351.       server_reply(from,ub,0,0);
  352.       if(!pos && (logging & L_UPLOAD)) ACTIONOK();
  353.       return;
  354.     case CC_INSTALL :
  355.       if(logging & L_INSTALL) ACTIONLOG1("INSTALL");
  356.       if (read_only) {
  357.     if((logging & L_ERR) && (logging & L_INSTALL))
  358.       ACTIONFAILED("Permission denied");
  359.         else if (logging & L_INSTALL) ACTIONOK() ;
  360.         send_error(from, ub, "Permission denied") ;
  361.     return;
  362.       }
  363.       if(!old)
  364.     if((pe = check_path(s1,l1,&pp)) ||
  365.        (pe = server_install(&pp,inet_num,port_num))) {
  366.       if((logging & L_ERR) && (logging & L_INSTALL)) ACTIONFAILED(pe);
  367.           else if (logging & L_INSTALL) ACTIONOK() ;
  368.           send_error(from, ub, pe) ;
  369.       return;
  370.     }
  371.       server_reply(from,ub,0,0);
  372.       if(logging & L_INSTALL) ACTIONOK();
  373.       return;
  374.     case CC_MAKE_DIR:
  375.       if(logging & L_MAKEDIR) ACTIONLOG1("MAKEDIR");
  376.       if (read_only) {
  377.     if((logging & L_ERR) && (logging & L_MAKEDIR))
  378.       ACTIONFAILED("Permission denied");
  379.         else if (logging & L_MAKEDIR) ACTIONOK() ;
  380.         send_error(from, ub, "Permission denied") ;
  381.     return;
  382.       }
  383.       if(!old)
  384.     if((pe = check_path(s1,l1,&pp)) ||
  385.        (pe=server_make_dir(&pp,inet_num))) {
  386.       if((logging & L_ERR) && (logging & L_MAKEDIR)) ACTIONFAILED(pe);
  387.           else if (logging & L_MAKEDIR) ACTIONOK() ;
  388.           send_error(from, ub, pe) ;
  389.       return;
  390.     }
  391.       if(pe = server_get_pro(&pp,s1,inet_num)) {
  392.     if((logging & L_ERR) && (logging & L_MAKEDIR)) ACTIONFAILED(pe);
  393.         else if (logging & L_MAKEDIR) ACTIONOK() ;
  394.         send_error(from, ub, pe) ;
  395.     return;
  396.       }
  397.       server_reply(from,ub,strlen(ub->buf)+1,0);
  398.       if(logging & L_MAKEDIR) ACTIONOK();
  399.       return;
  400.     case CC_GET_PRO :
  401.       if(logging & L_GETPRO) ACTIONLOG1("GETPRO");
  402.       if((pe=check_path(s1,l1,&pp)) || (pe=server_get_pro(&pp,s1,inet_num))) {
  403.     if((logging & L_ERR) && (logging & L_GETPRO)) ACTIONFAILED(pe);
  404.         else if (logging & L_GETPRO) ACTIONOK() ;
  405.         send_error(from, ub, pe) ;
  406.     return;
  407.       }
  408.       BB_WRITE4(ub->bb_pos,PRO_BYTES);
  409.       server_reply(from,ub,strlen(ub->buf)+1,PRO_BYTES);
  410.       if(logging & L_GETPRO) ACTIONOK();
  411.       return;
  412.     case CC_SET_PRO :
  413.       if(logging & L_SETPRO) ACTIONLOG1("SETPRO");
  414.       if(read_only) {
  415.     if((logging & L_ERR) && (logging & L_SETPRO))
  416.       ACTIONFAILED("Permission denied");
  417.         else if (logging & L_SETPRO) ACTIONOK() ;
  418.         send_error(from, ub, "Permission denied") ;
  419.     return;
  420.       }
  421.       if(!old)
  422.     if((pe = check_path(s1,l1,&pp)) ||
  423.        (pe = server_set_pro(&pp,s2,inet_num))) {
  424.       if((logging & L_ERR) && (logging & L_SETPRO)) ACTIONFAILED(pe);
  425.           else if (logging & L_SETPRO) ACTIONOK() ;
  426.           send_error(from, ub, pe) ;
  427.       return;
  428.     }
  429.       if(pe = server_get_pro(&pp,s1,inet_num)) {
  430.     if((logging & L_ERR) && (logging & L_SETPRO)) ACTIONFAILED(pe);
  431.         else if (logging & L_SETPRO) ACTIONOK() ;
  432.         send_error(from, ub, pe) ;
  433.     return;
  434.       }
  435.       BB_WRITE4(ub->bb_pos,PRO_BYTES);
  436.       server_reply(from,ub,strlen(ub->buf)+1,PRO_BYTES);
  437.       if(logging & L_SETPRO) ACTIONOK();
  438.       return;
  439.     case CC_GRAB_FILE:
  440.       if (!pos || read_only) {
  441.     if(logging & L_GRABFILE) ACTIONLOG1("GRABFILE");
  442.     if (read_only) {
  443.       if((logging & L_ERR) && (logging & L_GRABFILE))
  444.         ACTIONFAILED("Permission denied");
  445.           else if (logging & L_GRABFILE) ACTIONOK() ;
  446.           send_error(from, ub, "Permission denied") ;
  447.       return;
  448.     }
  449.       }
  450.       if(pe = check_path(s1,l1,&pp)) {
  451.     if (pos && (logging & L_ERR) && (logging & L_GRABFILE))
  452.       ACTIONLOG1("GRABFILE");
  453.     if((logging & L_ERR) && (logging & L_GRABFILE))  ACTIONFAILED(pe);
  454.         else if (!pos && (logging & L_GRABFILE)) ACTIONOK() ;
  455.         send_error(from, ub, pe) ;
  456.     return;
  457.       }
  458.       if(!old && !pos)
  459.     if(pe=server_secure_file(&pp,inet_num,port_num)) {
  460.       if((logging & L_ERR) && (logging & L_GRABFILE)) ACTIONFAILED(pe);
  461.           else if (logging & L_GRABFILE) ACTIONOK() ;
  462.           send_error(from, ub, pe) ;
  463.       return;
  464.     }
  465.       if(pe = server_grab_file(&pp, &fp, inet_num, port_num)) {
  466.     if (pos && (logging & L_ERR) && (logging & L_GRABFILE))
  467.       ACTIONLOG1("GRABFILE");
  468.     if((logging & L_ERR) && (logging & L_GRABFILE)) ACTIONFAILED(pe);
  469.         else if (!pos && (logging & L_GRABFILE)) ACTIONOK() ;
  470.         send_error(from, ub, pe) ;
  471.     return;
  472.       }
  473.       send_file(from,ub,fp,l2,s2);
  474.       fclose(fp);
  475.       if (!pos && (logging & L_GRABFILE)) ACTIONOK();
  476.       return;
  477.     case CC_GRAB_DONE:
  478.       if(logging & L_GRABFILE) ACTIONLOG1("GRABDONE");
  479.       if (read_only) {
  480.     if((logging & L_ERR) && (logging & L_GRABFILE))
  481.       ACTIONFAILED("Permission denied");
  482.         else if (logging & L_GRABFILE) ACTIONOK() ;
  483.         send_error(from, ub, "Permission denied") ;
  484.     return;
  485.       }
  486.       if(pe = check_path(s1,l1,&pp)) {
  487.     if((logging & L_ERR) && (logging & L_GRABFILE)) ACTIONFAILED(pe);
  488.         else if (logging & L_GRABFILE) ACTIONOK() ;
  489.         send_error(from, ub, pe) ;
  490.     return;
  491.       }
  492.       if(!old)
  493.     if(pe = server_grab_done(&pp,inet_num,port_num)) {
  494.       if((logging & L_ERR) && (logging & L_GRABFILE)) ACTIONFAILED(pe);
  495.           else if (logging & L_GRABFILE) ACTIONOK() ;
  496.           send_error(from, ub, pe) ;
  497.       return;
  498.     }
  499.       server_reply(from,ub,0,0);
  500.       if(logging & L_GRABFILE) ACTIONOK();
  501.       return;
  502.     default:
  503.       if(logging & L_ERR) {
  504.     ACTIONLOG0("UNKNOWN");
  505.     ACTIONINFO((" (%d)", ub->cmd));
  506.     ACTIONFAILED("Unknown FSP command");
  507.         send_error(from, ub, "Unknown FSP command") ;
  508.       }
  509.       return;
  510.   }
  511. }
  512.  
  513. static int arg_err PROTO0((void))
  514. {
  515.   fputs("Usage: fspd [-f configfile]\n", stderr);
  516.   exit(1);
  517. }
  518.  
  519. int main PROTO2(int, argc, char **, argv)
  520. {
  521.   inetd_mode = !strcmp(argv[0],"in.fspd");
  522.  
  523.   if(argc != 1) {
  524.     if (argc>3) arg_err() ;
  525.     if (strncmp(argv[1],"-f",2)) arg_err() ;
  526.     if (argc==3) config_file=argv[2] ;
  527.     else config_file=argv[1]+2 ;
  528.   }
  529.  
  530.   load_configuration();
  531.     
  532.   if(inetd_mode) {
  533.     init_inetd();
  534.     freopen(NULL_DEV,"r",stdin);
  535.     freopen(NULL_DEV,"w",stdout);
  536.     freopen(NULL_DEV,"w",stderr);
  537.   }
  538.  
  539.   /* clear all entries in file-cache */
  540.   clear_cache(fpcache, &cache_p);
  541.  
  542.   /* Moved setuid to here from below because log file was getting opened
  543.    * by root, and fspd could no longer write to the log file after the
  544.    * setuid. This should always open the file as run_uid
  545.    * Modified A.E.J.Fellows 9 March 93
  546.    */
  547.  
  548.   if(run_uid) if(setuid(run_uid) != 0) exit(1);
  549.   init_home_dir();
  550.  
  551.   if (logging && *logname) {
  552.     /* test to see if logfile can be written */
  553.     /* open it append mode so that it doesn't wipe the file when
  554.      * you are running under inetd. VMS uses file version number, so
  555.      * the old logfile won't be erased.
  556.      */
  557. #ifdef VMS
  558.     if((logfd=vms_open(logname, "w")) < 0) {
  559. #else
  560.     if((logfd=open(logname, O_WRONLY | O_APPEND | O_CREAT, 0644)) < 0) {
  561. #endif
  562.       fprintf(stderr, "Error opening logfile: %s, logging disabled.\n",
  563.           logname);
  564.       logging = 0; /* no logging */
  565.     }
  566.   }
  567.  
  568.   if(!inetd_mode) {
  569.     /* Fork and die to drop daemon into background   */
  570.     /* Added Alban E J Fellows 12 Jan 93             */
  571.     /* Moved by JT Traub to only do this if not running under inetd. */
  572.     if(daemonize) {
  573. #ifdef VMS
  574.       freopen(NULL_DEV,"r",stdin); /* speed up */
  575.       freopen(NULL_DEV,"w",stdout);
  576.       freopen(NULL_DEV,"w",stderr);
  577.       if (vfork() > 0)
  578. #else
  579.       if (fork() > 0)
  580. #endif
  581.     exit(0);
  582.     }
  583.     init_network(udp_port);
  584.   }
  585.  
  586.   /* setuid and init_home_dir move from here to above the logging file open */
  587.   init_htab();
  588.  
  589.   srandom(getpid());
  590.  
  591.   if(inetd_mode)
  592.     server_loop(120*1000L);  /* 2 minutes */
  593.   else
  594.     while(1) server_loop(-1L);
  595.  
  596.   exit(0);
  597. }
  598.